package com.hvgroup.modules.dify.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.hvgroup.modules.dify.service.DifyDatasetService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class DifyDatasetServiceImpl implements DifyDatasetService {

    @Value("${dify.api.url.root}")
    private String difyApiUrl;

    @Value("${dify.api.key.dataset}")
    private String difyKeyDataset;


    @Override
    public Mono<JsonNode> getDataset(String url, Map<String, Object> params) {

        return WebClient.builder().baseUrl(difyApiUrl).build()
                .get()
                .uri(uriBuilder -> {
                    uriBuilder.path(url);
                    // 仅添加收到的参数，避免 null / 空串
                    params.forEach((k, v) -> {
                        if (ObjectUtils.isNotEmpty(v)) {
                            uriBuilder.queryParam(k, v);
                        }
                    });
                    return uriBuilder.build();
                })
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + difyKeyDataset)
                .accept(MediaType.TEXT_EVENT_STREAM)
                .retrieve()
                .bodyToMono(JsonNode.class)
                .timeout(Duration.ofSeconds(10));

    }


    @Override
    public Mono<JsonNode> postDataset(Map<String, Object> map) {
        String url = (String) map.getOrDefault("url", "GET");
        String type = (String) map.get("type");
        Map<String, Object> params = (Map<String, Object>) map.get("params");

        if ("GET".equals(type)) {
            return getDataset(url, params);
        }
        return WebClient.builder().baseUrl(difyApiUrl).build()
                .post()
                .uri(uriBuilder -> {
                    uriBuilder.path(url);
                    // 仅添加收到的参数，避免 null / 空串
                    params.forEach((k, v) -> {
                        if (ObjectUtils.isNotEmpty(v)) {
                            uriBuilder.queryParam(k, v);
                        }
                    });
                    return uriBuilder.build();
                })
                .header(HttpHeaders.AUTHORIZATION, "Bearer " + difyKeyDataset)
                .accept(MediaType.TEXT_EVENT_STREAM)
                .retrieve()
                .bodyToMono(JsonNode.class)
                .timeout(Duration.ofSeconds(10));
    }


    @Override
    public Mono<JsonNode> postFileset(JsonNode metaJson, MultipartFile file) {
        String url = metaJson.path("url").asText();
        JsonNode dataNode = metaJson.path("data");

        try {
            // 1. 保存临时文件
            Path tempFile = Files.createTempFile("proxy-upload-", "-" + file.getOriginalFilename());
            file.transferTo(tempFile.toFile());

            // 2. 构造 multipart/form-data 请求
            MultipartBodyBuilder mb = new MultipartBodyBuilder();
            mb.part("data", dataNode.toString())
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
            mb.part("file", new FileSystemResource(tempFile))
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);

            // 3. 发送 POST 请求
            return WebClient.builder().baseUrl(difyApiUrl).build()
                    .post()
                    .uri(url)
                    .header(HttpHeaders.AUTHORIZATION, "Bearer " + difyKeyDataset)
                    .contentType(MediaType.MULTIPART_FORM_DATA)
                    .body(BodyInserters.fromMultipartData(mb.build()))
                    .retrieve()
                    .bodyToMono(JsonNode.class)
                    .doFinally(signalType -> {
                        try {
                            Files.deleteIfExists(tempFile);
                        } catch (IOException e) {
                            log.warn("删除临时文件失败: {}", e.getMessage());
                        }
                    });

        } catch (IOException e) {
            log.error("处理文件失败", e);
            return Mono.error(e);
        }
    }

}
